package com.cs307.redcross.client;

import java.io.Serializable;
import java.util.Date;
import java.util.Vector;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.datepicker.client.DatePicker;
import com.google.gwt.user.client.ui.Hyperlink;


@SuppressWarnings("deprecation")
public class EventsContent extends Content implements Serializable {
	private static final long serialVersionUID = -1189011235559691201L;
	private DatabaseHandlerServiceAsync databaseHandlerService = (DatabaseHandlerServiceAsync) GWT.create(DatabaseHandlerService.class);
	private final String relogString = "If this problem persists try relogging into the system.";
	
	Vector<Event> eventVector = new Vector<Event>();
	
	// the following are used when editing events
	Vector<Group> groupVector = new Vector<Group>();
	Vector<Reminder> reminderVector = new Vector<Reminder>();
	Vector<Person> personVector = new Vector<Person>();
	Vector<EventTemplate> eventTemplateVector = new Vector<EventTemplate>();
	
	Vector<Group> addedGroupVector = new Vector<Group>();
	Vector<Person> addedPersonVector = new Vector<Person>();
	
	String recurrence;
	
	int tempIndex;
	
	Event cancelEvent;
	Event selectedEvent;
	EventTemplate selectedEventTemplate;
	Reminder selectedReminder;
	Reminder saveReminder;
	Group selectedGroup;
	Person selectedPerson;
	
	Date newStartDate;
	Date newEndDate;
	
	Event eventCopy;
	Reminder newReminder;
	
	// UI Widgets
	ListBox eventsListbox;
	TextBox eventNameTextbox;
	TextArea eventDescriptionTextBox;
	ListBox groupsListBox;
	Button addEventButton;
	Button deleteEventButton;
	Button addReminderButton;
	Button deleteReminderButton;
	Button removeGroupButton;
	Button addGroupButton;
	Button editEventButton;
	ListBox remindersListBox;
	Button saveEventButton;
	Button cancelButton;
	PopupPanel popup;
	AddGroupPopupPanel agpp;
	AddReminderPopupPanel arpp;
	AddPersonPopupPanel appp;
	ListBox startTimeHourCombobox;
	ListBox startTimeMinuteCombobox;
	ListBox startTimeAMPMCombobox;
	ListBox endTimeHourCombobox;
	ListBox endTimeMinuteCombobox;
	ListBox endTimeAMPMCombobox;
	CheckBox recurringEventComboBox;
	PopupPanel startDatePopup;
	PopupPanel endDatePopup;
	DatePicker startDatePicker;
	DatePicker endDatePicker;
	Button inviteButton;
	InvitePeopleDialogBox ipdb;
	CheckBox eventTemplateCheckbox;
	ListBox eventTemplateCombobox;
	Label lblAdditionalPeople;
	ListBox personListBox;
	Button addPersonButton;
	Button removePersonButton;
	Label lblStartTime;
	Label lblStartDate;
	TextBox startDateTextBox;
	Label lblEndTime;
	Label lblStartTime_1;
	TextBox endDateTextBox;
	Anchor startDateAnchor;
	Anchor endDateAnchor;
	Label repeatsLabel;
	Label repeatPatternLabel;
	Hyperlink hprlnkEdit;
	
	public EventsContent() {
		
		ContentPanel.getInstance().showLoading(1, 80, 350);
		databaseHandlerService.getAllEvents(new AsyncCallback<Vector<Event>>() {
			
			@Override
			public void onSuccess(Vector<Event> result) {
				if (result != null && !result.isEmpty()) {
					for (Event event : result) {
						if (event == null)
							continue;
						
						eventVector.add(event);
						eventsListbox.addItem(event.getName());
					}
					ContentPanel.getInstance().hideLoadingPopup(1);
				}
			}
			
			@Override
			public void onFailure(Throwable caught) {
				ContentPanel.getInstance().hideLoadingPopup(1);
				Window.alert("Error: Failed to retrieve list of Events. Please try reloading the page. " + relogString);
				return;
			}
		});	
		
		databaseHandlerService.getAllEventTemplates(new AsyncCallback<Vector<EventTemplate>>() {
			
			@Override
			public void onSuccess(Vector<EventTemplate> result) {
				if (result != null && !result.isEmpty()) {
					for (EventTemplate et : result) {
						if (et == null)
							continue;
						
						eventTemplateVector.add(et);
						eventTemplateCombobox.addItem(et.getName());
					}
				}
			}
			
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Error: Failed to retrieve list of Event Templates. Please try reloading the page. " + relogString);
				return;
			}
		});
		
		AbsolutePanel absolutePanel = new AbsolutePanel();
		initWidget(absolutePanel);
		absolutePanel.setSize("1121px", "899px");
		
		Label lblSelectEvent = new Label("Events:");
		absolutePanel.add(lblSelectEvent, 10, 10);
		
		Label lblEventName = new Label("Event Name:");
		absolutePanel.add(lblEventName, 321, 45);
		lblEventName.setSize("79px", "18px");
		
		eventNameTextbox = new TextBox();
		absolutePanel.add(eventNameTextbox, 321, 69);
		eventNameTextbox.setSize("364px", "13px");
		
		eventDescriptionTextBox = new TextArea();
		absolutePanel.add(eventDescriptionTextBox, 319, 132);
		eventDescriptionTextBox.setSize("368px", "118px");
		eventDescriptionTextBox.setEnabled(false);		
		
		Label lblEventDescription = new Label("Event Description:");
		absolutePanel.add(lblEventDescription, 319, 108);
		lblEventDescription.setSize("122px", "18px");
		
		groupsListBox = new ListBox();
		groupsListBox.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent event) {
				if (groupsListBox.getSelectedIndex() != -1) {
					selectedGroup = addedGroupVector.get(groupsListBox.getSelectedIndex());
				}
			}
		});
		absolutePanel.add(groupsListBox, 319, 297);
		groupsListBox.setSize("376px", "106px");
		groupsListBox.setVisibleItemCount(9);
		
		Label lblAssociatedGroups = new Label("Associated Groups:");
		absolutePanel.add(lblAssociatedGroups, 319, 273);
		lblAssociatedGroups.setSize("122px", "18px");
		
		addEventButton = new Button("Add");
		addEventButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				reminderVector = new Vector<Reminder>();
				clearForm();
				
		        startTimeHourCombobox.setSelectedIndex(11);
		        startTimeMinuteCombobox.setSelectedIndex(1);
		        startTimeAMPMCombobox.setSelectedIndex(1);
		        
		        endTimeHourCombobox.setSelectedIndex(11);
		        endTimeMinuteCombobox.setSelectedIndex(1);
		        endTimeAMPMCombobox.setSelectedIndex(1);
				
				eventsListbox.setSelectedIndex(-1);
				selectedEvent = null;
				newStartDate = null;
				newEndDate = null;
				newReminder = null;
				
				groupVector = new Vector<Group>();
				addedGroupVector = new Vector<Group>();
				databaseHandlerService.getAllGroups(new AsyncCallback<Vector<Group>>() {
					
					@Override
					public void onSuccess(Vector<Group> result) {
						if (result != null && !result.isEmpty()) {
							for (Group group : result) {
								if (group == null)
									continue;
																
								groupVector.add(group);
							}
						}
					}
					
					@Override
					public void onFailure(Throwable caught) {
						Window.alert("Error: Failed to retrieve Groups. " + relogString);
					}
				});
				
				personVector = new Vector<Person>();
				addedPersonVector = new Vector<Person>();
				databaseHandlerService.getAllPeople(new AsyncCallback<Vector<Person>>() {
					
					@Override
					public void onSuccess(Vector<Person> result) {
						if (result != null && !result.isEmpty()) {
							for (Person person : result) {
								if (person == null)
									continue;
								
								if (person.getUsername().equals("dev"))
									continue;
								
								personVector.add(person);
							}
						}
					}
					
					@Override
					public void onFailure(Throwable caught) {
						Window.alert("Error: Failed to retrieve Volunteers. " + relogString);
					}
				});
				
				eventNameTextbox.setText("New Event");
				
				enableForm();
				eventsListbox.setEnabled(false);
			}
		});
		absolutePanel.add(addEventButton, 10, 604);
		
		deleteEventButton = new Button("Delete");
		deleteEventButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (selectedEvent != null && eventsListbox.getSelectedIndex() != -1) {
					popup = new PopupPanel();
					popup.setPopupPosition(400, 400);
					VerticalPanel vp = new VerticalPanel();
					vp.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
					vp.add(new Label("Are you sure you want to delete " + selectedEvent.getName() + "? You cannot undo this action."));
					
					Button yesButton = new Button("Yes");
					yesButton.addClickHandler(new ClickHandler() {
						
						@Override
						public void onClick(ClickEvent event) {
							popup.hide();
							popup.clear();
							databaseHandlerService.delete(selectedEvent, new AsyncCallback<Boolean>() {
								
								@Override
								public void onSuccess(Boolean result) {
									if (result) {
										eventVector.remove(eventsListbox.getSelectedIndex());
										eventsListbox.removeItem(eventsListbox.getSelectedIndex());
										selectedEvent = null;
										clearForm();
										disableForm();
										Window.alert("Event successfully deleted.");
									}
									else {
										Window.alert("An error ocurred while trying to delete the Event. Please try again. " + relogString);
									}
								}
								
								@Override
								public void onFailure(Throwable caught) {
									Window.alert("An error ocurred while trying to delete the Event. Please try again. " + relogString);
								}
							});
						}
					});
					
					Button noButton = new Button("No");
					noButton.addClickHandler(new ClickHandler() {
						
						@Override
						public void onClick(ClickEvent event) {
							popup.hide();
							popup.clear();
						}
					});
					
					SimplePanel sp = new SimplePanel();
					sp.setSize("5px", "20px");
					
					HorizontalPanel hp = new HorizontalPanel();
					hp.add(yesButton);
					hp.add(new Label("         "));
					hp.add(noButton);
					
					vp.add(sp);
					vp.add(hp);
					popup.add(vp);
					popup.show();
				}
			}
		});
		absolutePanel.add(deleteEventButton, 54, 604);
		deleteEventButton.setSize("53px", "24px");
		
		Label lblAssociatedReminders = new Label("Associated Reminders:");
		absolutePanel.add(lblAssociatedReminders, 722, 261);
		lblAssociatedReminders.setSize("143px", "18px");
		
		addReminderButton = new Button("Add");
		addReminderButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (startDateTextBox.getText().equals("") || newStartDate == null && selectedEvent.getStartTime() == null) {
					Window.alert("You must specify a start date for the event before adding any reminders to it");
					return;
				}
				
				if (newStartDate == null) {
					arpp = new AddReminderPopupPanel(selectedEvent.getStartTime());
				}
				else {
					arpp = new AddReminderPopupPanel(newStartDate);
				}
				
				arpp.setPopupPosition(eventDescriptionTextBox.getAbsoluteLeft(), eventDescriptionTextBox.getAbsoluteTop() - 140);
				arpp.setGlassEnabled(true);
				arpp.addReminderButton.addClickHandler(new ClickHandler() {
					
					@Override
					public void onClick(ClickEvent event) {
						if (arpp.messageTextArea.getText().replace(" ", "").equals("")) {
							Window.alert("Message is blank!");
							return;
						}
						
						if (arpp.specifyRelativeCheckbox.getValue()) {
							if (arpp.daysBeforeCombobox.getSelectedIndex() == 0 && arpp.hoursBeforeCombobox.getSelectedIndex() == 0 && arpp.minutesBeforeCombobox.getSelectedIndex() == 0) {
								Window.alert("Please specify a time before the event other than 0 days, 0 hours, and 0 minutes");
								return;
							}
							int minsBefore = arpp.daysBeforeCombobox.getSelectedIndex() * 24 * 60 + arpp.hoursBeforeCombobox.getSelectedIndex() * 60 + arpp.minutesBeforeCombobox.getSelectedIndex();
							arpp.newSendDate = new Date(arpp.eventDate.getTime() - minsBefore*60*1000);
						}
						else {
							if (arpp.sendDateTextBox.getText().replaceAll(" ", "").equals("")) {
								Window.alert("No send date specified!");
								return;
							}		
							
							arpp.newSendDate = new Date();
							if (arpp.sendTimeAMPMCombobox.getSelectedIndex() == 0) {
								
								if (arpp.sendTimeHourCombobox.getSelectedIndex() == 11) {
									arpp.newSendDate.setHours(0);
								}
								else {
									arpp.newSendDate.setHours(arpp.sendTimeHourCombobox.getSelectedIndex() + 1);
								}
							}
							else {
								if (arpp.sendTimeHourCombobox.getSelectedIndex() == 11) {
									arpp.newSendDate.setHours(12);
								}
								else {
									arpp.newSendDate.setHours(arpp.sendTimeHourCombobox.getSelectedIndex() + 13);
								}
							}
							arpp.newSendDate.setMinutes(arpp.sendTimeMinuteCombobox.getSelectedIndex());
						}
						
						Reminder newRem = new Reminder(new Event(), arpp.newSendDate, new Vector<Group>(), new Vector<Person>(), arpp.messageTextArea.getText(), arpp.deliveryMethodCombobox.getSelectedIndex());							
						reminderVector.add(newRem);
						remindersListBox.addItem(newRem.getTime().toString());
						arpp.hide();
						arpp.clear();
					}
				});
				arpp.cancelButton.addClickHandler(new ClickHandler() {
					
					@Override
					public void onClick(ClickEvent event) {
						arpp.hide();
						arpp.clear();
					}
				});				
				
				arpp.show();
			}
		});
		absolutePanel.add(addReminderButton, 722, 479);
		addReminderButton.setSize("38px", "24px");
		
		deleteReminderButton = new Button("Delete");
		deleteReminderButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				
				if (selectedReminder != null && remindersListBox.getSelectedIndex() != -1) {	
					if (selectedReminder.getID() == -1) {
						reminderVector.remove(remindersListBox.getSelectedIndex());
						remindersListBox.removeItem(remindersListBox.getSelectedIndex());
						selectedReminder = null;
						return;
					}
					
					databaseHandlerService.delete(selectedReminder, new AsyncCallback<Boolean>() {

						@Override
						public void onFailure(Throwable caught) {
							Window.alert("Error: Failed to delete the reminder. " + relogString);
						}

						@Override
						public void onSuccess(Boolean result) {
							reminderVector.remove(remindersListBox.getSelectedIndex());
							remindersListBox.removeItem(remindersListBox.getSelectedIndex());
							selectedReminder = null;
						}
						
					});					
				}
			}
		});
		absolutePanel.add(deleteReminderButton, 766, 479);
		deleteReminderButton.setSize("63px", "24px");
		
		removeGroupButton = new Button("Add");
		removeGroupButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (selectedGroup != null && groupsListBox.getSelectedIndex() != -1) {
					
					boolean duplicate = false;
					for (Group group : groupVector) {
						if (group == null)
							continue;
						
						if (group.getID() == selectedGroup.getID()) {
							duplicate = true;
							break;
						}
					}
					
					if (!duplicate) {
						groupVector.add(selectedGroup);
					}
					addedGroupVector.remove(selectedGroup);
					groupsListBox.removeItem(groupsListBox.getSelectedIndex());
					groupVector.add(selectedGroup);
					selectedGroup = null;
				}
			}
		});
		removeGroupButton.setText("Remove");
		absolutePanel.add(removeGroupButton, 363, 409);
		removeGroupButton.setSize("63px", "24px");
		
		addGroupButton = new Button("Add");
		addGroupButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {			
				//TODO: show loading
				agpp = new AddGroupPopupPanel(groupVector);
				agpp.setPopupPosition(eventDescriptionTextBox.getAbsoluteLeft(), eventDescriptionTextBox.getAbsoluteTop());
				agpp.setGlassEnabled(true);
				agpp.addGroupsButton.addClickHandler(new ClickHandler() {
					
					@Override
					public void onClick(ClickEvent event) {
						if (agpp.addedGroupVector != null && !agpp.addedGroupVector.isEmpty()) {
							for (Group group: agpp.addedGroupVector) {
								if (group == null)
									continue;
								
								groupsListBox.addItem(group.getName());
								addedGroupVector.add(group);
							}	
						}
						
						groupVector = new Vector<Group>(agpp.groupVector);
						
						agpp.hide();
						agpp.clear();
					}
				});
				agpp.cancelButton.addClickHandler(new ClickHandler() {
					
					@Override
					public void onClick(ClickEvent event) {
						agpp.hide();
						agpp.clear();
					}
				});				
				
				agpp.show();
			}
		});
		absolutePanel.add(addGroupButton, 319, 409);
		addGroupButton.setSize("38px", "24px");
		
		editEventButton = new Button("Edit");
		editEventButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (eventsListbox.getSelectedIndex() != -1) {
					enableForm();
					eventsListbox.setEnabled(false);
				}
			}
		});
		absolutePanel.add(editEventButton, 113, 604);
		editEventButton.setSize("38px", "24px");
		
		remindersListBox = new ListBox();
		remindersListBox.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent event) {
				if (remindersListBox.getSelectedIndex() != -1) {
					selectedReminder = reminderVector.get(remindersListBox.getSelectedIndex());
				}
			}
		});
		remindersListBox.setVisibleItemCount(9);
		absolutePanel.add(remindersListBox, 722, 285);
		remindersListBox.setSize("376px", "188px");
		
		eventsListbox = new ListBox();
		eventsListbox.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent event) {
				populateForm();
				if (selectedEvent != null) {
					cancelEvent = new Event(selectedEvent);
				}
			}
		});
		eventsListbox.setVisibleItemCount(30);
		absolutePanel.add(eventsListbox, 10, 34);
		eventsListbox.setSize("259px", "564px");
		
		saveEventButton = new Button("Save Event");
		saveEventButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
								
				if (eventNameTextbox.getText().replace(" ","").equals("")) {
					Window.alert("The Event has no name!");
					return;
				}
				if (eventDescriptionTextBox.getText().replace(" ","").equals("")) {
					Window.alert("The Event has no description!");
					return;
				}
				if (startDateTextBox.getText().replace(" ","").equals("")) {
					Window.alert("The Event has no start date!");
					return;
				}
				if (endDateTextBox.getText().replace(" ","").equals("")) {
					Window.alert("The Event has no end date!");
					return;
				}
								
				if (selectedEvent != null) {
					eventCopy = new Event(selectedEvent);
				}
				else {
					selectedEvent = new Event();
					eventCopy = null;
				}
								
				selectedEvent.setName(eventNameTextbox.getText());
				selectedEvent.setDescription(eventDescriptionTextBox.getText());
				
				if (newStartDate == null)
					newStartDate = new Date();
				if (newEndDate == null)
					newEndDate = new Date();
								
				if (startTimeAMPMCombobox.getSelectedIndex() == 0) {
					if (startTimeHourCombobox.getSelectedIndex() == 11) {
						newStartDate.setHours(0);
					}
					else {
						newStartDate.setHours(startTimeHourCombobox.getSelectedIndex() + 1);
					}
				}
				else {
					if (startTimeHourCombobox.getSelectedIndex() == 11) {
						newStartDate.setHours(12);
					}
					else {
						newStartDate.setHours(startTimeHourCombobox.getSelectedIndex() + 13);
					}
				}
												
				if (endTimeAMPMCombobox.getSelectedIndex() == 0) {
					if (endTimeHourCombobox.getSelectedIndex() == 11) {
						newEndDate.setHours(0);
					}
					else {
						newEndDate.setHours(endTimeHourCombobox.getSelectedIndex() + 1);
					}
				}
				else {
					if (endTimeHourCombobox.getSelectedIndex() == 11) {
						newEndDate.setHours(12);
					}
					else {
						newEndDate.setHours(endTimeHourCombobox.getSelectedIndex() + 13);
					}
				}
				
				newStartDate.setMinutes(startTimeMinuteCombobox.getSelectedIndex());
				newEndDate.setMinutes(endTimeMinuteCombobox.getSelectedIndex());
				
				selectedEvent.setStartTime(newStartDate);
				selectedEvent.setEndTime(newEndDate);
								
				selectedEvent.setGroups(new Vector<Group>());
				
				if (groupsListBox.getItemCount() > 0) {
					for (Group group : addedGroupVector) {
						if (group == null)
							continue;
						
						selectedEvent.getGroups().add(group);
					}
				}
				
				selectedEvent.setPeople(new Vector<Person>());
					
				if (personListBox.getItemCount() > 0) {
					for (Person person : addedPersonVector) {
						if (person == null)
							continue;

						selectedEvent.getPeople().add(person);
					}
				}
				
				if (remindersListBox.getItemCount() < 1) {
					reminderVector = new Vector<Reminder>();
				}
				
				//TODO: recurrence
							
				databaseHandlerService.write(selectedEvent, new AsyncCallback<Integer>() {

					@Override
					public void onFailure(Throwable caught) {
						Window.alert("Error: Failed to save Event. " + relogString + caught.toString());
						if (eventCopy != null) {
							selectedEvent = new Event(eventCopy);
						}
					}

					@Override
					public void onSuccess(Integer result) {
						if (result > -1) {
							if (selectedEvent.getId() < 0)
								selectedEvent.setId(result);
														
							// update all the associated reminders
							for (Reminder reminder : reminderVector) {
								
								if (reminder == null)
									continue;
								
								reminder.setGroups(new Vector<Group>());
								reminder.setPeople(new Vector<Person>());
								
								if (groupsListBox.getItemCount() > 0) {
									for (Group group : addedGroupVector) {
										if (group == null)
											continue;
																						
										reminder.getGroups().add(group);
									}
								}
								
								if (personListBox.getItemCount() > 0) {
									for (Person person : addedPersonVector) {
										if (person == null)
											continue;
										
										reminder.getPeople().add(person);
									}
								}
											
								
								if (reminder.getEvent().getID() != selectedEvent.getID()) {
									reminder.setEvent(selectedEvent);
								}
								databaseHandlerService.write(reminder, new AsyncCallback<Integer>() {

									@Override
									public void onFailure(Throwable caught) {
										Window.alert("Error: the event saved successfully but the reminders failed to save. " + relogString + caught.toString());
									}

									@Override
									public void onSuccess(Integer result) {
										if (result < 0) {
											Window.alert("Error: the event saved successfully but the reminders failed to save. " + relogString);
										}
										else{
											tempIndex = result;
										}
									}								
								});
								reminder.setId(tempIndex);
							}
							if (eventCopy == null) {
								eventsListbox.addItem(selectedEvent.getName());
								eventVector.add(selectedEvent);
								
								if (eventsListbox.getItemCount() > 0) 
									eventsListbox.setSelectedIndex(groupVector.size() - 1);
							}
							
							disableForm();
							eventsListbox.setEnabled(true);
							Window.alert("The event was saved succesfully.");
						}
					}
				});
			}
		});
		absolutePanel.add(saveEventButton, 10, 604);
		saveEventButton.setSize("97px", "24px");
		
		cancelButton = new Button("Cancel");
		cancelButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (cancelEvent != null) {
					selectedEvent = new Event(cancelEvent);
				}
					
				if (selectedEvent != null && eventsListbox.getSelectedIndex() != -1) {
					populateForm();
					disableForm();
				}
				else {
					clearForm();
					disableForm();
				}
				eventsListbox.setEnabled(true);
			}
		});
		absolutePanel.add(cancelButton, 113, 604);
		cancelButton.setSize("97px", "24px");
		
		lblAdditionalPeople = new Label("Additional Volunteers:");
		absolutePanel.add(lblAdditionalPeople, 319, 447);
		lblAdditionalPeople.setSize("134px", "18px");
		
		personListBox = new ListBox();
		personListBox.setVisibleItemCount(9);
		personListBox.setEnabled(false);
		absolutePanel.add(personListBox, 319, 471);
		personListBox.setSize("376px", "106px");
		personListBox.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent event) {
				if (personListBox.getSelectedIndex() != -1) {
					selectedPerson = addedPersonVector.get(personListBox.getSelectedIndex());
				}
			}
		});
		
		addPersonButton = new Button("Add");
		addPersonButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				//TODO: show loading
				appp = new AddPersonPopupPanel(personVector);
				appp.setPopupPosition(eventDescriptionTextBox.getAbsoluteLeft(), eventDescriptionTextBox.getAbsoluteTop());
				appp.setGlassEnabled(true);
				
				appp.addedPersonVector = new Vector<Person>();
				appp.addPersonButton.addClickHandler(new ClickHandler() {
					
					@Override
					public void onClick(ClickEvent event) {
						if (appp.addedPersonVector != null && !appp.addedPersonVector.isEmpty()) {
							for (Person person: appp.addedPersonVector) {
								if (person == null)
									continue;
								
								personListBox.addItem(person.getFirstName() + " " + person.getLastName());
								addedPersonVector.add(person);
							}	
						}
						
						personVector = new Vector<Person>(appp.personVector);
						
						appp.hide();
						appp.clear();
					}
				});
				appp.cancelButton.addClickHandler(new ClickHandler() {
					
					@Override
					public void onClick(ClickEvent event) {
						appp.hide();
						appp.clear();
					}
				});				
				
				appp.show();
			}
		});
		addPersonButton.setEnabled(false);
		absolutePanel.add(addPersonButton, 319, 583);
		addPersonButton.setSize("38px", "24px");
		
		removePersonButton = new Button("Remove");
		removePersonButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (selectedPerson != null && personListBox.getSelectedIndex() != -1) {					
						personVector.add(selectedPerson);
						addedPersonVector.remove(selectedPerson);
						personListBox.removeItem(personListBox.getSelectedIndex());
						selectedPerson = null;				
				}
			}
		});
		removePersonButton.setEnabled(false);
		absolutePanel.add(removePersonButton, 363, 583);
		removePersonButton.setSize("63px", "24px");
		
		lblStartTime = new Label("Start Time:");
		absolutePanel.add(lblStartTime, 722, 45);
		lblStartTime.setSize("70px", "18px");
		
		lblStartDate = new Label("Start Date:");
		absolutePanel.add(lblStartDate, 945, 45);
		lblStartDate.setSize("70px", "18px");
		
		startDateTextBox = new TextBox();
		startDateTextBox.setEnabled(false);
		absolutePanel.add(startDateTextBox, 945, 69);
		startDateTextBox.setSize("141px", "13px");
		
		lblEndTime = new Label("End Time:");
		absolutePanel.add(lblEndTime, 722, 111);
		lblEndTime.setSize("70px", "18px");
		
		lblStartTime_1 = new Label("End Date:");
		absolutePanel.add(lblStartTime_1, 945, 111);
		lblStartTime_1.setSize("63px", "18px");
		
		endDateTextBox = new TextBox();
		endDateTextBox.setEnabled(false);
		absolutePanel.add(endDateTextBox, 945, 135);
		endDateTextBox.setSize("141px", "13px");
		
		startTimeHourCombobox = new ListBox();
		startTimeHourCombobox.addItem("1");
		startTimeHourCombobox.addItem("2");
		startTimeHourCombobox.addItem("3");
		startTimeHourCombobox.addItem("4");
		startTimeHourCombobox.addItem("5");
		startTimeHourCombobox.addItem("6");
		startTimeHourCombobox.addItem("7");
		startTimeHourCombobox.addItem("8");
		startTimeHourCombobox.addItem("9");
		startTimeHourCombobox.addItem("10");
		startTimeHourCombobox.addItem("11");
		startTimeHourCombobox.addItem("12");
		absolutePanel.add(startTimeHourCombobox, 722, 69);
		startTimeHourCombobox.setSize("50px", "18px");
		
		startTimeMinuteCombobox = new ListBox();
		startTimeMinuteCombobox.addItem("00");
		startTimeMinuteCombobox.addItem("01");
		startTimeMinuteCombobox.addItem("02");
		startTimeMinuteCombobox.addItem("03");
		startTimeMinuteCombobox.addItem("04");
		startTimeMinuteCombobox.addItem("05");
		startTimeMinuteCombobox.addItem("06");
		startTimeMinuteCombobox.addItem("07");
		startTimeMinuteCombobox.addItem("08");
		startTimeMinuteCombobox.addItem("09");
		startTimeMinuteCombobox.addItem("10");
		startTimeMinuteCombobox.addItem("11");
		startTimeMinuteCombobox.addItem("12");
		startTimeMinuteCombobox.addItem("13");
		startTimeMinuteCombobox.addItem("14");
		startTimeMinuteCombobox.addItem("15");
		startTimeMinuteCombobox.addItem("16");
		startTimeMinuteCombobox.addItem("17");
		startTimeMinuteCombobox.addItem("18");
		startTimeMinuteCombobox.addItem("19");
		startTimeMinuteCombobox.addItem("20");
		startTimeMinuteCombobox.addItem("21");
		startTimeMinuteCombobox.addItem("22");
		startTimeMinuteCombobox.addItem("23");
		startTimeMinuteCombobox.addItem("24");
		startTimeMinuteCombobox.addItem("25");
		startTimeMinuteCombobox.addItem("26");
		startTimeMinuteCombobox.addItem("27");
		startTimeMinuteCombobox.addItem("28");
		startTimeMinuteCombobox.addItem("29");
		startTimeMinuteCombobox.addItem("30");
		startTimeMinuteCombobox.addItem("31");
		startTimeMinuteCombobox.addItem("32");
		startTimeMinuteCombobox.addItem("33");
		startTimeMinuteCombobox.addItem("34");
		startTimeMinuteCombobox.addItem("35");
		startTimeMinuteCombobox.addItem("36");
		startTimeMinuteCombobox.addItem("37");
		startTimeMinuteCombobox.addItem("38");
		startTimeMinuteCombobox.addItem("39");
		startTimeMinuteCombobox.addItem("40");
		startTimeMinuteCombobox.addItem("41");
		startTimeMinuteCombobox.addItem("42");
		startTimeMinuteCombobox.addItem("43");
		startTimeMinuteCombobox.addItem("44");
		startTimeMinuteCombobox.addItem("45");
		startTimeMinuteCombobox.addItem("46");
		startTimeMinuteCombobox.addItem("47");
		startTimeMinuteCombobox.addItem("48");
		startTimeMinuteCombobox.addItem("49");
		startTimeMinuteCombobox.addItem("50");
		startTimeMinuteCombobox.addItem("51");
		startTimeMinuteCombobox.addItem("52");
		startTimeMinuteCombobox.addItem("53");
		startTimeMinuteCombobox.addItem("54");
		startTimeMinuteCombobox.addItem("55");
		startTimeMinuteCombobox.addItem("56");
		startTimeMinuteCombobox.addItem("57");
		startTimeMinuteCombobox.addItem("58");
		startTimeMinuteCombobox.addItem("59");
		absolutePanel.add(startTimeMinuteCombobox, 777, 69);
		startTimeMinuteCombobox.setSize("50px", "18px");
		
		startTimeAMPMCombobox = new ListBox();
		startTimeAMPMCombobox.addItem("AM");
		startTimeAMPMCombobox.addItem("PM");
		absolutePanel.add(startTimeAMPMCombobox, 845, 69);
		startTimeAMPMCombobox.setSize("53px", "18px");
		
		endTimeHourCombobox = new ListBox();
		endTimeHourCombobox.addItem("1");
		endTimeHourCombobox.addItem("2");
		endTimeHourCombobox.addItem("3");
		endTimeHourCombobox.addItem("4");
		endTimeHourCombobox.addItem("5");
		endTimeHourCombobox.addItem("6");
		endTimeHourCombobox.addItem("7");
		endTimeHourCombobox.addItem("8");
		endTimeHourCombobox.addItem("9");
		endTimeHourCombobox.addItem("10");
		endTimeHourCombobox.addItem("11");
		endTimeHourCombobox.addItem("12");
		absolutePanel.add(endTimeHourCombobox, 722, 135);
		endTimeHourCombobox.setSize("51px", "18px");
		
		endTimeMinuteCombobox = new ListBox();
		endTimeMinuteCombobox.addItem("00");
		endTimeMinuteCombobox.addItem("01");
		endTimeMinuteCombobox.addItem("02");
		endTimeMinuteCombobox.addItem("03");
		endTimeMinuteCombobox.addItem("04");
		endTimeMinuteCombobox.addItem("05");
		endTimeMinuteCombobox.addItem("06");
		endTimeMinuteCombobox.addItem("07");
		endTimeMinuteCombobox.addItem("08");
		endTimeMinuteCombobox.addItem("09");
		endTimeMinuteCombobox.addItem("10");
		endTimeMinuteCombobox.addItem("11");
		endTimeMinuteCombobox.addItem("12");
		endTimeMinuteCombobox.addItem("13");
		endTimeMinuteCombobox.addItem("14");
		endTimeMinuteCombobox.addItem("15");
		endTimeMinuteCombobox.addItem("16");
		endTimeMinuteCombobox.addItem("17");
		endTimeMinuteCombobox.addItem("18");
		endTimeMinuteCombobox.addItem("19");
		endTimeMinuteCombobox.addItem("20");
		endTimeMinuteCombobox.addItem("21");
		endTimeMinuteCombobox.addItem("22");
		endTimeMinuteCombobox.addItem("23");
		endTimeMinuteCombobox.addItem("24");
		endTimeMinuteCombobox.addItem("25");
		endTimeMinuteCombobox.addItem("26");
		endTimeMinuteCombobox.addItem("27");
		endTimeMinuteCombobox.addItem("28");
		endTimeMinuteCombobox.addItem("29");
		endTimeMinuteCombobox.addItem("30");
		endTimeMinuteCombobox.addItem("31");
		endTimeMinuteCombobox.addItem("32");
		endTimeMinuteCombobox.addItem("33");
		endTimeMinuteCombobox.addItem("34");
		endTimeMinuteCombobox.addItem("35");
		endTimeMinuteCombobox.addItem("36");
		endTimeMinuteCombobox.addItem("37");
		endTimeMinuteCombobox.addItem("38");
		endTimeMinuteCombobox.addItem("39");
		endTimeMinuteCombobox.addItem("40");
		endTimeMinuteCombobox.addItem("41");
		endTimeMinuteCombobox.addItem("42");
		endTimeMinuteCombobox.addItem("43");
		endTimeMinuteCombobox.addItem("44");
		endTimeMinuteCombobox.addItem("45");
		endTimeMinuteCombobox.addItem("46");
		endTimeMinuteCombobox.addItem("47");
		endTimeMinuteCombobox.addItem("48");
		endTimeMinuteCombobox.addItem("49");
		endTimeMinuteCombobox.addItem("50");
		endTimeMinuteCombobox.addItem("51");
		endTimeMinuteCombobox.addItem("52");
		endTimeMinuteCombobox.addItem("53");
		endTimeMinuteCombobox.addItem("54");
		endTimeMinuteCombobox.addItem("55");
		endTimeMinuteCombobox.addItem("56");
		endTimeMinuteCombobox.addItem("57");
		endTimeMinuteCombobox.addItem("58");
		endTimeMinuteCombobox.addItem("59");
		absolutePanel.add(endTimeMinuteCombobox, 777, 135);
		endTimeMinuteCombobox.setSize("50px", "18px");
		
		endTimeAMPMCombobox = new ListBox();
		endTimeAMPMCombobox.addItem("AM");
		endTimeAMPMCombobox.addItem("PM");
		absolutePanel.add(endTimeAMPMCombobox, 845, 135);
		endTimeAMPMCombobox.setSize("53px", "18px");
		
		recurringEventComboBox = new CheckBox("This is a recurring event");
		recurringEventComboBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
			public void onValueChange(ValueChangeEvent<Boolean> event) {
				if (recurringEventComboBox.getValue()) {
					repeatsLabel.setVisible(true);
					if (recurrence != null) {
						repeatPatternLabel.setText(RecurrenceDialogBox.run(recurrence));
					}
				}
				else {
					repeatsLabel.setVisible(false);
					repeatPatternLabel.setText("");
				}
			}
		});
		absolutePanel.add(recurringEventComboBox, 722, 176);
		
		startDateAnchor = new Anchor();
		startDateAnchor.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event){
				startDatePopup.setPopupPosition(startDateAnchor.getAbsoluteLeft(), startDateAnchor.getAbsoluteTop());
				startDatePopup.show();
			}
		});
		startDateAnchor.setText("Calendar");
		absolutePanel.add(startDateAnchor, 1043, 45);
		startDateAnchor.setSize("51px", "18px");
		
		endDateAnchor = new Anchor();
		endDateAnchor.addClickHandler(new ClickHandler(){
			
			@Override
			public void onClick(ClickEvent event){
				endDatePopup.setPopupPosition(endDateAnchor.getAbsoluteLeft(), endDateAnchor.getAbsoluteTop());
				endDatePopup.show();
			}
		});
		endDateAnchor.setText("Calendar");
		absolutePanel.add(endDateAnchor, 1043, 111);
		endDateAnchor.setSize("51px", "18px");
		
		startDatePopup = new PopupPanel(true);
		startDatePicker = new DatePicker();
		
		startDatePopup.add(startDatePicker);
		
		startDatePicker.addValueChangeHandler(new ValueChangeHandler<Date>() {
			
			@Override
			public void onValueChange(ValueChangeEvent<Date> event) {
		        newStartDate = event.getValue();
		        if(endDateTextBox.getText().equals(""))
		        	newEndDate = event.getValue();
		        	
				if (startTimeAMPMCombobox.getSelectedIndex() == 0) {
					if (startTimeHourCombobox.getSelectedIndex() == 11) {
						newStartDate.setHours(0);
					}
					else {
						newStartDate.setHours(startTimeHourCombobox.getSelectedIndex() + 1);
					}
				}
				else {
					if (startTimeHourCombobox.getSelectedIndex() == 11) {
						newStartDate.setHours(12);
					}
					else {
						newStartDate.setHours(startTimeHourCombobox.getSelectedIndex() + 13);
					}
				}
												
				if (endTimeAMPMCombobox.getSelectedIndex() == 0) {
					if (endTimeHourCombobox.getSelectedIndex() == 11) {
						newEndDate.setHours(0);
					}
					else {
						newEndDate.setHours(endTimeHourCombobox.getSelectedIndex() + 1);
					}
				}
				else {
					if (endTimeHourCombobox.getSelectedIndex() == 11) {
						newEndDate.setHours(12);
					}
					else {
						newEndDate.setHours(endTimeHourCombobox.getSelectedIndex() + 13);
					}
				}
				
				newStartDate.setMinutes(startTimeMinuteCombobox.getSelectedIndex());
				newEndDate.setMinutes(endTimeMinuteCombobox.getSelectedIndex());
		        String dateString = DateTimeFormat.getFormat("MM/dd/yy").format(newStartDate);
		        startDateTextBox.setText(dateString);
		        
		        if(endDateTextBox.getText().equals(""))
		        	endDateTextBox.setText(dateString);
		        
		        startDatePopup.hide();
			}
		});
	    
		endDatePopup = new PopupPanel(true);
		endDatePicker = new DatePicker();
		
		endDatePopup.add(endDatePicker);
		
	    endDatePicker.addValueChangeHandler(new ValueChangeHandler<Date>() {
		public void onValueChange(ValueChangeEvent<Date> event) {
	        newEndDate = event.getValue();
	        String dateString = DateTimeFormat.getFormat("MM/dd/yy").format(newEndDate);
	        endDateTextBox.setText(dateString);
	        endDatePopup.hide();
	      }
	    });
		
		inviteButton = new Button("Invite");
		absolutePanel.add(inviteButton, 644, 583);
		
		repeatsLabel = new Label("Repeats:");
		absolutePanel.add(repeatsLabel, 722, 201);
		
		repeatPatternLabel = new Label("Doesn't repeat");
		absolutePanel.add(repeatPatternLabel, 777, 201);
		
		eventTemplateCheckbox = new CheckBox("Create event from template:");
		eventTemplateCheckbox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
			public void onValueChange(ValueChangeEvent<Boolean> event) {
				if (eventTemplateCheckbox.getValue()) {
					eventTemplateCombobox.setEnabled(true);
					clearForm();
			
					selectedEventTemplate = null;
					if (eventTemplateCombobox.getSelectedIndex() != -1) {
						selectedEventTemplate = eventTemplateVector.get(eventTemplateCombobox.getSelectedIndex());
						
						if (selectedEventTemplate != null) {
							
							groupVector = new Vector<Group>();
							addedGroupVector = new Vector<Group>();
							databaseHandlerService.getAllGroups(new AsyncCallback<Vector<Group>>() {
								
								@Override
								public void onSuccess(Vector<Group> result) {
									if (result != null && !result.isEmpty()) {						
										for (Group group : result) {
											if (group == null)
												continue;
											
											if (selectedEventTemplate.getGroups() != null) {
												boolean duplicate = false;
												for (Group gr : selectedEventTemplate.getGroups()) {
													if (gr == null)
														continue;
													
													if (gr.getID() == group.getID()) {
														duplicate = true;
														break;
													}
												}
											
												if (!duplicate) {
													groupVector.add(group);
												}
												else {
													addedGroupVector.add(group);
													groupsListBox.addItem(group.getName());
												}
											}
											else {
												groupVector.add(group);
											}
										}
									}
								}
								
								@Override
								public void onFailure(Throwable caught) {
									Window.alert("Error: Failed to retrieve Groups. " + relogString);
								}
							});
							
							personVector = new Vector<Person>();
							addedPersonVector = new Vector<Person>();
							databaseHandlerService.getAllPeople(new AsyncCallback<Vector<Person>>() {
								
								@Override
								public void onSuccess(Vector<Person> result) {
									if (result != null && !result.isEmpty()) {
										for (Person person : result) {
											if (person == null)
												continue;
											
											if (person.getUsername().equals("dev"))
												continue;
											
											if (selectedEventTemplate.getPeople() != null) {
												boolean duplicate = false;
												for (Person pr : selectedEventTemplate.getPeople()) {
													if (pr == null)
														continue;
													
													if (pr.getID() == person.getID()) {
														duplicate = true;
														break;
													}
												}
											
												if (!duplicate) {
													personVector.add(person);
												}
												else {
													addedPersonVector.add(person);
													personListBox.addItem(person.getFirstName() + " " + person.getLastName());
												}
											}
											else {
												personVector.add(person);
											}
										}
									}
								}
								
								@Override
								public void onFailure(Throwable caught) {
									Window.alert("Error: Failed to retrieve Volunteers. " + relogString);
								}
							});
							
							if (selectedEventTemplate.getRecurrence() != null) {
								recurrence = selectedEventTemplate.getRecurrence();
							}
														
							eventNameTextbox.setText(selectedEventTemplate.getName());
							eventDescriptionTextBox.setText(selectedEventTemplate.getDescription());
							
							if (selectedEventTemplate.getStartTime() != null & selectedEventTemplate.getEndTime() != null) {
								if (selectedEventTemplate.getStartTime().getHours() == 0) {
									startTimeHourCombobox.setSelectedIndex(11);
									startTimeAMPMCombobox.setSelectedIndex(0);
								}
								else if (selectedEventTemplate.getStartTime().getHours() < 12) {
									startTimeHourCombobox.setSelectedIndex(selectedEventTemplate.getStartTime().getHours() - 1);
									startTimeAMPMCombobox.setSelectedIndex(0);
								}
								else if (selectedEventTemplate.getStartTime().getHours() == 12) {
									startTimeHourCombobox.setSelectedIndex(11);
									startTimeAMPMCombobox.setSelectedIndex(1);
								}
								else if (selectedEventTemplate.getStartTime().getHours() > 12) {
									startTimeHourCombobox.setSelectedIndex(selectedEventTemplate.getStartTime().getHours() - 13);
									startTimeAMPMCombobox.setSelectedIndex(1);
								}
								
								if (selectedEventTemplate.getEndTime().getHours() == 0) {
									endTimeHourCombobox.setSelectedIndex(11);
									endTimeAMPMCombobox.setSelectedIndex(0);
								}
								else if (selectedEventTemplate.getEndTime().getHours() < 12) {
									endTimeHourCombobox.setSelectedIndex(selectedEventTemplate.getEndTime().getHours() - 1);
									endTimeAMPMCombobox.setSelectedIndex(0);
								}
								else if (selectedEventTemplate.getEndTime().getHours() == 12) {
									endTimeHourCombobox.setSelectedIndex(11);
									endTimeAMPMCombobox.setSelectedIndex(1);
								}
								else if (selectedEventTemplate.getEndTime().getHours() > 12) {
									endTimeHourCombobox.setSelectedIndex(selectedEventTemplate.getEndTime().getHours() - 13);
									endTimeAMPMCombobox.setSelectedIndex(1);
								}
								
								startTimeMinuteCombobox.setSelectedIndex(selectedEventTemplate.getStartTime().getMinutes());
								endTimeMinuteCombobox.setSelectedIndex(selectedEventTemplate.getEndTime().getMinutes());
								
								newStartDate = selectedEventTemplate.getStartTime();
								newEndDate = selectedEventTemplate.getEndTime();
								
								startDateTextBox.setText("");
								endDateTextBox.setText("");
							}
							
							//TODO: set recurrence for the event
						}
					}
				}
				else {
					eventTemplateCheckbox.setValue(false);
					eventTemplateCombobox.setEnabled(false);
				}
			}
		});
		absolutePanel.add(eventTemplateCheckbox, 317, 17);
		
		eventTemplateCombobox = new ListBox();
		eventTemplateCombobox.addChangeHandler(new ChangeHandler() {
			
			@Override
			public void onChange(ChangeEvent event) {
				selectedEventTemplate = null;
				if (eventTemplateCombobox.getSelectedIndex() != -1) {
					selectedEventTemplate = eventTemplateVector.get(eventTemplateCombobox.getSelectedIndex());
					personListBox.clear();
					groupsListBox.clear();
					
					if (selectedEventTemplate != null) {
						
						groupVector = new Vector<Group>();
						addedGroupVector = new Vector<Group>();
						databaseHandlerService.getAllGroups(new AsyncCallback<Vector<Group>>() {
							
							@Override
							public void onSuccess(Vector<Group> result) {
								if (result != null && !result.isEmpty()) {						
									for (Group group : result) {
										if (group == null)
											continue;
										
										if (selectedEventTemplate.getGroups() != null) {
											boolean duplicate = false;
											for (Group gr : selectedEventTemplate.getGroups()) {
												if (gr == null)
													continue;
												
												if (gr.getID() == group.getID()) {
													duplicate = true;
													break;
												}
											}
										
											if (!duplicate) {
												groupVector.add(group);
											}
											else {
												addedGroupVector.add(group);
												groupsListBox.addItem(group.getName());
											}
										}
										else {
											groupVector.add(group);
										}
									}
								}
							}
							
							@Override
							public void onFailure(Throwable caught) {
								Window.alert("Error: Failed to retrieve Groups. " + relogString);
							}
						});
						
						personVector = new Vector<Person>();
						addedPersonVector = new Vector<Person>();
						databaseHandlerService.getAllPeople(new AsyncCallback<Vector<Person>>() {
							
							@Override
							public void onSuccess(Vector<Person> result) {
								if (result != null && !result.isEmpty()) {
									for (Person person : result) {
										if (person == null)
											continue;
										
										if (person.getUsername().equals("dev"))
											continue;
										
										if (selectedEventTemplate.getPeople() != null) {
											boolean duplicate = false;
											for (Person pr : selectedEventTemplate.getPeople()) {
												if (pr == null)
													continue;
												
												if (pr.getID() == person.getID()) {
													duplicate = true;
													break;
												}
											}
										
											if (!duplicate) {
												personVector.add(person);
											}
											else {
												addedPersonVector.add(person);
												personListBox.addItem(person.getFirstName() + " " + person.getLastName());
											}
										}
										else {
											personVector.add(person);
										}
									}
								}
							}
							
							@Override
							public void onFailure(Throwable caught) {
								Window.alert("Error: Failed to retrieve Volunteers. " + relogString);
							}
						});
						
						if (selectedEventTemplate.getRecurrence() != null) {
							recurrence = selectedEventTemplate.getRecurrence();
						}
						                                       
						
						eventNameTextbox.setText(selectedEventTemplate.getName());
						eventDescriptionTextBox.setText(selectedEventTemplate.getDescription());
						
						if (selectedEventTemplate.getStartTime() != null & selectedEventTemplate.getEndTime() != null) {
							if (selectedEventTemplate.getStartTime().getHours() == 0) {
								startTimeHourCombobox.setSelectedIndex(11);
								startTimeAMPMCombobox.setSelectedIndex(0);
							}
							else if (selectedEventTemplate.getStartTime().getHours() < 12) {
								startTimeHourCombobox.setSelectedIndex(selectedEventTemplate.getStartTime().getHours() - 1);
								startTimeAMPMCombobox.setSelectedIndex(0);
							}
							else if (selectedEventTemplate.getStartTime().getHours() == 12) {
								startTimeHourCombobox.setSelectedIndex(11);
								startTimeAMPMCombobox.setSelectedIndex(1);
							}
							else if (selectedEventTemplate.getStartTime().getHours() > 12) {
								startTimeHourCombobox.setSelectedIndex(selectedEventTemplate.getStartTime().getHours() - 13);
								startTimeAMPMCombobox.setSelectedIndex(1);
							}
							
							if (selectedEventTemplate.getEndTime().getHours() == 0) {
								endTimeHourCombobox.setSelectedIndex(11);
								endTimeAMPMCombobox.setSelectedIndex(0);
							}
							else if (selectedEventTemplate.getEndTime().getHours() < 12) {
								endTimeHourCombobox.setSelectedIndex(selectedEventTemplate.getEndTime().getHours() - 1);
								endTimeAMPMCombobox.setSelectedIndex(0);
							}
							else if (selectedEventTemplate.getEndTime().getHours() == 12) {
								endTimeHourCombobox.setSelectedIndex(11);
								endTimeAMPMCombobox.setSelectedIndex(1);
							}
							else if (selectedEventTemplate.getEndTime().getHours() > 12) {
								endTimeHourCombobox.setSelectedIndex(selectedEventTemplate.getEndTime().getHours() - 13);
								endTimeAMPMCombobox.setSelectedIndex(1);
							}
							
							startTimeMinuteCombobox.setSelectedIndex(selectedEventTemplate.getStartTime().getMinutes());
							endTimeMinuteCombobox.setSelectedIndex(selectedEventTemplate.getEndTime().getMinutes());
							
							startDateTextBox.setText(selectedEventTemplate.getStartTimeString());
							endDateTextBox.setText(selectedEventTemplate.getEndTimeString());	
					}
						
						//TODO: set recurrence for the event
					}
				}
			}
		});
		absolutePanel.add(eventTemplateCombobox, 503, 17);
		eventTemplateCombobox.setSize("391px", "18px");
		
		
		inviteButton.addClickHandler(new ClickHandler(){
			
			@Override
			public void onClick(ClickEvent event){
				if (selectedEvent == null) {
					Window.alert("Event must be saved first in order to invite people.");
					return;
				}
				ipdb = new InvitePeopleDialogBox(selectedEvent.getFreePeople());
				ipdb.setPopupPosition(eventDescriptionTextBox.getAbsoluteLeft(), eventDescriptionTextBox.getAbsoluteTop());
				ipdb.setGlassEnabled(true);
				
				personVector = new Vector<Person>();
				addedPersonVector = new Vector<Person>();
				ipdb.addPersonButton.addClickHandler(new ClickHandler() {
					
					@Override
					public void onClick(ClickEvent event) {
						if (ipdb.addedPersonVector != null && !ipdb.addedPersonVector.isEmpty()) {
							for (Person person: ipdb.addedPersonVector) {
								if (person == null)
									continue;
								
								//TODO: add send invitation method							
							}	
						}
						
						personVector = new Vector<Person>(appp.personVector);
						
						ipdb.hide();
						ipdb.clear();
					}
				});
				ipdb.cancelButton.addClickHandler(new ClickHandler() {
					
					@Override
					public void onClick(ClickEvent event) {
						ipdb.hide();
						ipdb.clear();
					}
				});				
				
				ipdb.show();
			}
		});
		
		hprlnkEdit = new Hyperlink("Edit", false, "newHistoryToken");
		hprlnkEdit.addClickListener(new ClickListener() {
			public void onClick(Widget sender) {
				//TODO: recurrence				
			}
		});
		absolutePanel.add(hprlnkEdit, 886, 176);
		hprlnkEdit.setVisible(false);
		
		disableForm();	
		repeatsLabel.setVisible(false);
		repeatPatternLabel.setText("");
		clearForm();
	}
	
	
	// populate form ********************************************************************************************
	private void populateForm() {
		eventTemplateCheckbox.setValue(false);
		addedGroupVector = new Vector<Group>();
		addedPersonVector = new Vector<Person>();
		reminderVector = new Vector<Reminder>();
		
		if (eventsListbox.getSelectedIndex() != -1) {
			clearForm();
			selectedEvent = eventVector.get(eventsListbox.getSelectedIndex());
			
			//TODO: show loading
			reminderVector = new Vector<Reminder>();
			databaseHandlerService.getReminders(selectedEvent, new AsyncCallback<Vector<Reminder>>() {
				
				@Override
				public void onSuccess(Vector<Reminder> result) {
					if (result != null && !result.isEmpty()) {								
						for (Reminder reminder : result) {
							if (reminder == null)
								continue;
							
							remindersListBox.addItem(reminder.getTime().toString());
							reminderVector.add(reminder);
						}
					}
				}
				
				@Override
				public void onFailure(Throwable caught) {
					Window.alert("Error: Failed to retrieve Reminders. " + relogString);
				}
			});
			
			//TODO: show loading
			groupVector = new Vector<Group>();
			addedGroupVector = new Vector<Group>();
			databaseHandlerService.getAllGroups(new AsyncCallback<Vector<Group>>() {
				
				@Override
				public void onSuccess(Vector<Group> result) {
					if (result != null && !result.isEmpty()) {						
						for (Group group : result) {
							if (group == null)
								continue;
							
							if (selectedEvent.getGroups() != null) {
								boolean duplicate = false;
								for (Group gr : selectedEvent.getGroups()) {
									if (gr == null)
										continue;
									
									if (gr.getID() == group.getID()) {
										duplicate = true;
										break;
									}
								}
							
								if (!duplicate) {
									groupVector.add(group);
								}
								else {
									addedGroupVector.add(group);
									groupsListBox.addItem(group.getName());
								}
							}
							else {
								groupVector.add(group);
							}
						}
					}
				}
				
				@Override
				public void onFailure(Throwable caught) {
					Window.alert("Error: Failed to retrieve Groups. " + relogString);
				}
			});
			
			//TODO: show loading
			personVector = new Vector<Person>();
			addedPersonVector = new Vector<Person>();
			databaseHandlerService.getAllPeople(new AsyncCallback<Vector<Person>>() {
				
				@Override
				public void onSuccess(Vector<Person> result) {
					if (result != null && !result.isEmpty()) {
						for (Person person : result) {
							if (person == null)
								continue;
							
							if (person.getUsername().equals("dev"))
								continue;
							
							if (selectedEvent.getPeople() != null) {
								boolean duplicate = false;
								for (Person pr : selectedEvent.getPeople()) {
									if (pr == null)
										continue;
									
									if (pr.getID() == person.getID()) {
										duplicate = true;
										break;
									}
								}
							
								if (!duplicate) {
									personVector.add(person);
								}
								else {
									addedPersonVector.add(person);
									personListBox.addItem(person.getFirstName() + " " + person.getLastName());
								}
							}
							else {
								personVector.add(person);
							}
						}
					}
				}
				
				@Override
				public void onFailure(Throwable caught) {
					Window.alert("Error: Failed to retrieve Volunteers. " + relogString);
				}
			});
			
			if (selectedEvent.getRecurrence() != null) {
				recurrence = selectedEvent.getRecurrence();
			}

			if (selectedEvent != null) {
				eventNameTextbox.setText(selectedEvent.getName());
				eventDescriptionTextBox.setText(selectedEvent.getDescription());
				
				newStartDate = selectedEvent.getStartTime();
				newEndDate = selectedEvent.getEndTime();
				
				if (selectedEvent.getStartTime().getHours() == 0) {
					startTimeHourCombobox.setSelectedIndex(11);
					startTimeAMPMCombobox.setSelectedIndex(0);
				}
				else if (selectedEvent.getStartTime().getHours() < 12) {
					startTimeHourCombobox.setSelectedIndex(selectedEvent.getStartTime().getHours() - 1);
					startTimeAMPMCombobox.setSelectedIndex(0);
				}
				else if (selectedEvent.getStartTime().getHours() == 12) {
					startTimeHourCombobox.setSelectedIndex(11);
					startTimeAMPMCombobox.setSelectedIndex(1);
				}
				else if (selectedEvent.getStartTime().getHours() > 12) {
					startTimeHourCombobox.setSelectedIndex(selectedEvent.getStartTime().getHours() - 13);
					startTimeAMPMCombobox.setSelectedIndex(1);
				}
				
				if (selectedEvent.getEndTime().getHours() == 0) {
					endTimeHourCombobox.setSelectedIndex(11);
					endTimeAMPMCombobox.setSelectedIndex(0);
				}
				else if (selectedEvent.getEndTime().getHours() < 12) {
					endTimeHourCombobox.setSelectedIndex(selectedEvent.getEndTime().getHours() - 1);
					endTimeAMPMCombobox.setSelectedIndex(0);
				}
				else if (selectedEvent.getEndTime().getHours() == 12) {
					endTimeHourCombobox.setSelectedIndex(11);
					endTimeAMPMCombobox.setSelectedIndex(1);
				}
				else if (selectedEvent.getEndTime().getHours() > 12) {
					endTimeHourCombobox.setSelectedIndex(selectedEvent.getEndTime().getHours() - 13);
					endTimeAMPMCombobox.setSelectedIndex(1);
				}
				
				startTimeMinuteCombobox.setSelectedIndex(selectedEvent.getStartTime().getMinutes());
				endTimeMinuteCombobox.setSelectedIndex(selectedEvent.getEndTime().getMinutes());
				
				startDateTextBox.setText(selectedEvent.getStartTimeString());
				endDateTextBox.setText(selectedEvent.getEndTimeString());				
				//TODO: show recurrence
			}
			
			disableForm();
			eventsListbox.setEnabled(true);
		}
	}
	
	private void disableForm() {
		recurringEventComboBox.setVisible(false);
		inviteButton.setVisible(false);
		
		eventNameTextbox.setEnabled(false);
		eventDescriptionTextBox.setEnabled(false);
		eventTemplateCheckbox.setEnabled(false);
		eventTemplateCombobox.setEnabled(false);
		
		groupsListBox.setEnabled(false);
		addGroupButton.setEnabled(false);
		removeGroupButton.setEnabled(false);
		
		remindersListBox.setEnabled(false);
		addReminderButton.setEnabled(false);
		deleteReminderButton.setEnabled(false);
		
		personListBox.setEnabled(false);
		addPersonButton.setEnabled(false);
		removePersonButton.setEnabled(false);
		inviteButton.setEnabled(false);
		
		startTimeAMPMCombobox.setEnabled(false);
		startTimeHourCombobox.setEnabled(false);
		startTimeMinuteCombobox.setEnabled(false);
		
		endTimeAMPMCombobox.setEnabled(false);
		endTimeHourCombobox.setEnabled(false);
		endTimeMinuteCombobox.setEnabled(false);
		
		startDateAnchor.setEnabled(false);
		endDateAnchor.setEnabled(false);
		
		recurringEventComboBox.setEnabled(false);
		
		addEventButton.setEnabled(true);
		editEventButton.setEnabled(true);
		deleteEventButton.setEnabled(true);
		
		hprlnkEdit.setVisible(false);
		
		saveEventButton.setVisible(false);
		cancelButton.setVisible(false);
	}
	
	private void enableForm() {
		eventNameTextbox.setEnabled(true);
		eventDescriptionTextBox.setEnabled(true);
		eventTemplateCheckbox.setEnabled(true);
		
		groupsListBox.setEnabled(true);
		addGroupButton.setEnabled(true);
		removeGroupButton.setEnabled(true);
		
		remindersListBox.setEnabled(true);
		addReminderButton.setEnabled(true);
		deleteReminderButton.setEnabled(true);
		
		personListBox.setEnabled(true);
		addPersonButton.setEnabled(true);
		removePersonButton.setEnabled(true);
		inviteButton.setEnabled(true);
		
		startTimeAMPMCombobox.setEnabled(true);
		startTimeHourCombobox.setEnabled(true);
		startTimeMinuteCombobox.setEnabled(true);
		
		endTimeAMPMCombobox.setEnabled(true);
		endTimeHourCombobox.setEnabled(true);
		endTimeMinuteCombobox.setEnabled(true);
		
		startDateAnchor.setEnabled(true);
		endDateAnchor.setEnabled(true);
		
		//recurringEventComboBox.setEnabled(true);
		
		addEventButton.setEnabled(false);
		editEventButton.setEnabled(false);
		deleteEventButton.setEnabled(false);
		
		saveEventButton.setVisible(true);
		cancelButton.setVisible(true);
	}
	
	private void clearForm() {
		eventNameTextbox.setText("");
		eventDescriptionTextBox.setText("");
		
		recurrence = null;
		
		startTimeAMPMCombobox.setSelectedIndex(1);
		startTimeHourCombobox.setSelectedIndex(11);
		startTimeMinuteCombobox.setSelectedIndex(1);
		startDateTextBox.setText("");
		
		endTimeAMPMCombobox.setSelectedIndex(1);
		endTimeHourCombobox.setSelectedIndex(11);
		endTimeMinuteCombobox.setSelectedIndex(1);
		endDateTextBox.setText("");
		
		recurringEventComboBox.setValue(false);
		
		groupsListBox.clear();
		remindersListBox.clear();
		personListBox.clear();
	}
}
